﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace GameEngine.MoveHistory
{
    /// <summary>
    /// Class responsible for keeping history of moves
    /// </summary>
    public class MoveHistoryFacade
    {
        ///// <summary>
        ///// Attributes used for keeping save gamehistory state when working with game manager, used 
        ///// for some move evaluation purposes
        ///// </summary>
        //Stack<Move> _savedMovesDone;
        //Stack<Move> _savedMovesToDo;
        //BitBoard _savedPosition;

        private IMoveHistoryModel _moveModel = null;

        /// <summary>
        /// Reference to gameboard set by GameManagerBuilder
        /// </summary>
        public GameBoard GameBoard
        {
            get
            {
                return _moveModel.GameBoard;
            }
            set
            {
                _moveModel.GameBoard = value;
            }
        }

        /// <summary>
        /// Allocates stacks
        /// </summary>
        public MoveHistoryFacade(enumHistoryModel eType)
        {
            _moveModel = HistoryModelFactory.Create(eType);
        }


        #region Main Public Methods To Work With Game


        /// <summary>
        /// Returns all moves done
        /// </summary>
        /// <param name="list"></param>
        public void GetMoveList(List<Move> list)
        {
            _moveModel.GetMoveList(list);
        }

        /// <summary>
        /// Returns moves done
        /// </summary>
        /// <param name="list"></param>
        public void GetMovesDone(List<Move> list)
        {
            _moveModel.GetMovesDone(list);
        }

        /// <summary>
        /// Returns moves to do
        /// </summary>
        /// <param name="list"></param>
        public void GetMovesToDo(List<Move> list)
        {
            _moveModel.GetMovesToDo(list);
        }

        ///// <summary>
        ///// Saves game state to storage attributes
        ///// </summary>
        //public void SaveGameState()
        //{
        //    _savedMovesDone = new Stack<Move>();
        //    _savedMovesToDo = new Stack<Move>();

        //    while (m_MovesDone.Count != 0)
        //    {
        //        _savedMovesDone.Push(m_MovesDone.Pop());
        //    }
        //    while (m_MovesToDo.Count != 0)
        //    {
        //        _savedMovesToDo.Push(m_MovesToDo.Pop());
        //    }

        //    _savedPosition = GameBoard.PackGameBoard();
        //}

        ///// <summary>
        ///// Restores previously saved game state
        ///// </summary>
        //public void RestoreGameState()
        //{
        //    GameBoard.UnpackGameBoard(_savedPosition);

        //    m_MovesDone.Clear();
        //    while (_savedMovesDone.Count != 0)
        //        m_MovesDone.Push(_savedMovesDone.Pop());

        //    m_MovesToDo.Clear();
        //    while (_savedMovesToDo.Count != 0)
        //        m_MovesToDo.Push(_savedMovesToDo.Pop());
        //}

        ///// <summary>
        ///// Returns the last move done
        ///// </summary>
        ///// <returns></returns>
        //public Move GetLastMove()
        //{
        //    if (m_MovesDone.Count == 0)
        //        return null;
        //    Move move = m_MovesDone.Pop();
        //    m_MovesDone.Push(move);
        //    return move;
        //}

        /// <summary>
        /// Adds a new move to the end
        /// </summary>
        public void AddMove(Move move)
        {
            _moveModel.AddMove(move);
        }

        /// <summary>
        /// Makes game history empty, e.g. for starting board editor
        /// </summary>
        public void ClearMoves()
        {
            _moveModel.ClearMoves();
        }

        /// <summary>
        /// Clears moves to do
        /// </summary>
        public void ClearMovesToDo()
        {
            _moveModel.ClearMovesToDo();
        }

        #endregion

        #region Public methods for navigation in the game

        /// <summary>
        /// Returns the number of moves done
        /// </summary>
        /// <returns></returns>
        public int GetMovesDoneCount()
        {
            return _moveModel.GetMovesDoneCount();
        }

        /// <summary>
        /// Returns the current index of move
        /// </summary>
        /// <returns></returns>
        public int GetMoveIndex()
        {
            return _moveModel.GetMoveIndex();
        }

        /// <summary>
        /// Moves to the move with specific game index
        /// </summary>
        /// <param name="idx"></param>
        public void MoveToIndex(int idx)
        {
            _moveModel.MoveToIndex(idx);
        }

        /// <summary>
        /// Are we able to move forward?
        /// </summary>
        /// <returns></returns>
        public bool CanMoveForward()
        {
            return _moveModel.CanMoveForward();
        }

        /// <summary>
        /// Are we able to move back
        /// </summary>
        /// <returns></returns>
        public bool CanMoveBack()
        {
            return _moveModel.CanMoveBack();
        }

        /// <summary>
        /// Move back in the game
        /// </summary>
        public void MoveBack()
        {
            _moveModel.MoveBack();
        }

        /// <summary>
        /// Move forward in the game
        /// </summary>
        public void MoveForward()
        {
            _moveModel.MoveForward();
        }

        /// <summary>
        /// Move to the beginning of the game
        /// </summary>
        public void MoveToBeginning()
        {
            while (CanMoveBack() == true)
                MoveBack();
        }

        /// <summary>
        /// Move to the end of the game
        /// </summary>
        public void MoveToEnd()
        {
            while (CanMoveForward() == true)
                MoveForward();
        }

        #endregion
    }
}
